import 'package:flutter/material.dart';

class ExcelView extends StatelessWidget {
  const ExcelView({
    super.key,
    this.ratios,
    required this.children,
    this.lineColor,
    this.radius,
    this.height,
    this.width,
    this.columnHeightCallback,
    this.horizontalScrollable = false,
    this.verticalScrollable = false,
  })  : assert(verticalScrollable && height != null),
        assert(horizontalScrollable && width != null);
  final List<int>? ratios;
  final List<List<Widget>> children;
  final Color? lineColor;
  final BorderRadius? radius;
  final bool horizontalScrollable;
  final bool verticalScrollable;
  final double? height;
  final double? width;
  final double Function(int index)? columnHeightCallback;

  Color get _lineColor {
    return lineColor ?? const Color(0xffcccccc);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: _lineColor),
        borderRadius: radius,
      ),
      width: width,
      height: height,
      child: horizontalScrollable
          ? MediaQuery.removePadding(
              removeTop: true,
              removeBottom: true,
              context: context,
              child: ListView(
                physics: const NeverScrollableScrollPhysics(),
                children: _buildVerticalList(),
              ))
          : Column(
              children: _buildVerticalList(),
            ),
    );
  }

  List<Widget> _buildVerticalList() {
    return List.generate(children.length, (i) {
      final child = _buildHorizontalList(i, children[i]);
      return horizontalScrollable
          ? SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              physics: const NeverScrollableScrollPhysics(),
              child: child,
            )
          : child;
    });
  }

  Widget _buildHorizontalList(int column, List<Widget> l) {
    double h = 80;
    if (columnHeightCallback != null) {
      h = columnHeightCallback!(column);
    }

    return Row(
      children: l
          .asMap()
          .map((i, val) {
            int flex = 1;
            if (ratios != null) {
              flex = ratios![i];
            }
            return MapEntry(
                i,
                Expanded(
                  flex: flex,
                  child: Container(
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                      border: Border(right: BorderSide(color: _lineColor)),
                    ),
                    height: h,
                    child: val,
                  ),
                ));
          })
          .values
          .toList(),
    );
  }
}
